package com.iwuyc.tools.commons.util.math;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * 16、32、64进制枚举
 *
 * @author Neil
 * since 2022.1
 */
@Getter
@Slf4j
public enum HexEnum {

    /**
     * 16进制;
     * <br>
     * Prefix: 0x;
     * <br>
     * Mask:0000 1111
     */
    HEX_0("0x", 0x0F, 4),
    /**
     * 32进制;
     * <br>
     * Prefix:1x;
     * <br>
     * Mask:0001 1111
     */
    HEX_1("1x", 0x1F, 5),
    /**
     * 64进制;
     * <br>
     * Prefix:2x;
     * <br>
     * Mask:0011 1111
     */
    HEX_2("2x", 0x3F, 6);

    /**
     * 十六进制字典表，最大支持64进制。
     */
    private static final char[] HEX_CHARS = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '-', '_'};
    /**
     * 根据char查询对应的十进制值
     */
    private static final Map<Character, Integer> NUMBER_BY_CHAR;
    /**
     * 格式化后的映射表，对应关系字符串
     */
    private static final String MAPPER_FORMAT;

    static {
        Map<Character, Integer> temp = new HashMap<>(64);
        StringBuilder formatBuilder = new StringBuilder(64 * 7);
        formatBuilder.append('{');
        for (int i = 0; i < HEX_CHARS.length; i++) {
            char hexChar = HEX_CHARS[i];
            formatBuilder.append('\'').append(hexChar).append('\'').append(':').append(i).append(',');
            temp.put(hexChar, i);
        }
        formatBuilder.setCharAt(formatBuilder.length() - 1, '}');
        MAPPER_FORMAT = formatBuilder.toString();
        NUMBER_BY_CHAR = Collections.unmodifiableMap(temp);
    }

    /**
     * 进制前缀。16进制：0x；32进制：1x；64进制：2x；
     */
    private final String hexPrefix;
    /**
     * 进制掩码
     */
    private final int hexMasks;
    /**
     * 掩码长度，用于移位
     */
    private final int maskLength;

    HexEnum(String hexPrefix, int hexMasks, int maskLength) {
        this.hexPrefix = hexPrefix;
        this.hexMasks = hexMasks;
        this.maskLength = maskLength;
    }

    /**
     * 获取hex char的顺序表
     *
     * @return hex char的顺序表
     */
    public static char[] getHexChars() {
        return Arrays.copyOf(HEX_CHARS, HEX_CHARS.length);
    }

    /**
     * 将进制映射表中的字符转换为对应的数字。
     *
     * @param character 待转换的字符
     * @return 字符所对应的数字
     * @throws NumberFormatException 如果字符不在进制映射表中，将抛出该异常
     */
    public static int char2Number(char character) throws NumberFormatException {
        Integer index = NUMBER_BY_CHAR.get(character);
        if (null == index) {
            throw new NumberFormatException("未知的进制字符：" + character);
        }
        return index;
    }

    /**
     * 格式化输出64进制的映射表，以字符串的形式输出。
     *
     * @return 64进制的映射表字符串
     */
    public static String formatMappings() {
        return MAPPER_FORMAT;
    }
}
